/** <!--------------------------------------------------------------------------------------------->
 * @file RevModel.h
 *
 * GSvn - A Graphical Client for SVN
 * Copyright (C) 2012  Karl Krach, gsvn@bluespirit.la
 *
 * This program is free software: you can redistribute it and/or modify
 * it under the terms of the GNU General Public License as published by
 * the Free Software Foundation, either version 3 of the License, or
 * (at your option) any later version.
 *
 * This program is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU General Public License for more details.
 *
 * You should have received a copy of the GNU General Public License
 * along with this program.  If not, see <http://www.gnu.org/licenses/>.
 <!---------------------------------------------------------------------------------------------> */

#ifndef REVMODEL_H
#define REVMODEL_H

// -- includes --
#include <QObject>
#include "SvnHistoryListener.h"
#include "SvnConnection.h"
#include "RevModelItem.h"
#include <QRegExp>

// --- forward declarations ---
// --- namespaces ---
// --- defines ---
typedef int Revision;
#ifndef QSP
#define QSP QSharedPointer
#endif



/** <!--------------------------------------------------------------------------------------------->
 * Model to provide a interface to the storrage of the SVN revisions.
 *
 * @author	Karl Krach, <gsvn@bluespirit.la>
 * @since	2012-01-21
 <!---------------------------------------------------------------------------------------------> */
class RevModel : public QObject, public SvnHistoryListener
{
	Q_OBJECT

	/* Con-/Destructor */
public:

	/** <!----------------------------------------------------------------------------------------->
	 * Creates the RevModel object
	 <!-----------------------------------------------------------------------------------------> */
	RevModel();

	/** <!----------------------------------------------------------------------------------------->
	 * Deletes the RevModel object
	 <!-----------------------------------------------------------------------------------------> */
	virtual ~RevModel();


	/* Methods */
public:

	/** <!----------------------------------------------------------------------------------------->
	 * Sets the branch pattern to divide all revision into several branches
	 <!-----------------------------------------------------------------------------------------> */
	void setBranchPattern( const QRegExp& rBranchPattern )
	{
		if( !rBranchPattern.isValid() )
			throw QString("Cannot set invalid branch pattern!");

		m_oBranchPattern = rBranchPattern;
	}


	/* Signals */
signals:

	/** <!----------------------------------------------------------------------------------------->
	 * Signal is emitted when a revision has changed (e.g. it was newly loaded, e.g. triggered by
	 * SL_TriggerRevisionBroadcast()) or the data in the model has changed
	 <!-----------------------------------------------------------------------------------------> */
	void SI_RevisionChanged( QSP<RevModelItem> pRevModelItem );

	/** <!----------------------------------------------------------------------------------------->
	 * Signal is emitted when a branch is created or is changed
	 <!-----------------------------------------------------------------------------------------> */
	void SI_BranchChanged( BranchIndex iIndex, QString strName );

	/** <!----------------------------------------------------------------------------------------->
	 * Signal is emitted when the status has changed
	 <!-----------------------------------------------------------------------------------------> */
	void SI_StatusChanged( const QString& strStatus );


	/* Public Slots */
public slots:

	/** <!----------------------------------------------------------------------------------------->
	 * Requests specified revisions and broadcasts them via SI_RevisionChanged()
	 <!-----------------------------------------------------------------------------------------> */
	void SL_TriggerRevisionBroadcast( const SvnRevisionIdentifier& oRevID );


	/* Override SvnHistoryListener */
public:

	/** <!----------------------------------------------------------------------------------------->
	 * Callback method to be called on each history element (triggered by 'svn log')
	 *
	 *
	 * @param iRevision     (in) SVN revision
	 * @param oDateTime     (in) SVN commit time
	 * @param strMessage    (in) SVN log message
	 * @param strAuthor     (in) SVN author
	 * @param aChangedFiles (in) changed files in this revision
	 * @param aCopyInfo     (in) SVN copy info (branch info)
	 <!-----------------------------------------------------------------------------------------> */
	void OnHistoryReceive( int iRevision, QDateTime oDateTime, QString strMessage,
	                       QString strAuthor, QStringList aChangedFiles,
	                       QList<SvnCopyInfo> aCopyInfo );

	/** <!----------------------------------------------------------------------------------------->
	 * Callback method to be called on every progress-update
	 *
	 * @param fBytesReceived (in) Received bytes
	 * @param fThrougput     (in) Throughput in kB/sec
	 <!-----------------------------------------------------------------------------------------> */
	void OnHistoryProgress( float fBytesReceived, float fThrouput );

	/** <!----------------------------------------------------------------------------------------->
	 * Callback method to be called on every statistic update
	 *
	 * @param strCommand (in) Name of last command
	 * @param iMsNeeded  (in) Milliseconds need for the last command
	 * @param fBytesReceived (in) Received bytes
	 <!-----------------------------------------------------------------------------------------> */
	void OnHistoryStatistics( QString strCommand, int iMsNeeded, float fBytesReceived );


	/* Members */
public:

	/** <!----------------------------------------------------------------------------------------->
	 * Pointer to a SVN connection object, to receive the data from
	 <!-----------------------------------------------------------------------------------------> */
	SvnConnection m_oConnection;

	/** <!----------------------------------------------------------------------------------------->
	 * The branch pattern is used to divide all revision into several branches
	 <!-----------------------------------------------------------------------------------------> */
	QRegExp m_oBranchPattern;

	/** <!----------------------------------------------------------------------------------------->
	 * List of all branches
	 <!-----------------------------------------------------------------------------------------> */
	QStringList m_aBranches;

};	// END class RevModel

#endif // REVMODEL_H
